package services

import (
	"TaskAssignmentSystem/internal/admin/dao"
	"TaskAssignmentSystem/pkg/db/redis"
	"TaskAssignmentSystem/pkg/utils"
	"fmt"
	"time"
)

type SystemAdvService struct {
}

func (s *SystemAdvService) AdvCreate(advText, advPath, hyperlink string, sort, adminId uint) error {
	var adv dao.SystemAdv
	adv.AdvText = advText
	adv.AdvPath = advPath
	adv.Hyperlink = hyperlink
	adv.OnlineTime = time.Now()
	adv.OfflineTime = time.Now().AddDate(1, 0, 0)
	adv.Sort = sort
	adv.Status = dao.AdvOnlineStatus
	adv.SystemAdminId = adminId
	var advDao dao.Common[dao.SystemAdv]
	if err := advDao.CreateOne(adv).Error; err != nil {
		return err
	}
	//创建redis 过期事件(广告开启和关闭)
	expirationOpen := adv.OnlineTime.Unix() - time.Now().In(utils.LocationZone).Unix()
	openKey := fmt.Sprintf("adv_open@%d", adv.Id)
	if setNX := redis.RedisGClient.SetNX(openKey, "", time.Duration(expirationOpen)*time.Second).Err(); setNX != nil {
		return setNX
	}
	//广告关闭
	expirationClose := adv.OfflineTime.Unix() - time.Now().In(utils.LocationZone).Unix()
	closeKey := fmt.Sprintf("adv_close@%d", adv.Id)
	if setNX := redis.RedisGClient.SetNX(closeKey, "", time.Duration(expirationClose)*time.Second).Err(); setNX != nil {
		return setNX
	}
	return nil
}

type AdvListResponse struct {
	dao.SystemAdv
	TotalClicks     int64 `json:"total_clicks"`
	NotRepeatClicks int64 `json:"not_repeat_clicks"`
}

func (s *SystemAdvService) AdvFindAll(page, pageSize int64) (int64, []AdvListResponse, error) {
	var advServe CommonService[dao.SystemAdv]
	advServe.Page = page
	advServe.PageSize = pageSize
	advServe.Order = "sort"
	if advList, err := advServe.SelectList(); err != nil {
		return 0, nil, err
	} else {
		var res []AdvListResponse

		// 查询点击量
		var advLogDao dao.Common[dao.SystemAdvLog]
		for _, v := range advList.Data {
			item := AdvListResponse{SystemAdv: v}
			if totalClicks, err := advLogDao.Count(map[string]interface{}{"adv_id": v.Id}); err != nil {
				return 0, nil, err
			} else {
				item.TotalClicks = totalClicks
			}
			sql := fmt.Sprintf("SELECT count(a.system_user_id) as total FROM (SELECT system_user_id,count(id) as total FROM tas_system_adv_log WHERE adv_id = %d GROUP BY system_user_id) a", v.Id)
			item.NotRepeatClicks, _ = advLogDao.RawCount(sql, "total")
			res = append(res, item)
		}
		return advList.Total, res, nil
	}
}

func (s *SystemAdvService) AdvFindById(advId uint) (*dao.SystemAdv, error) {
	var advDao dao.Common[dao.SystemAdv]
	if adv, err := advDao.First(map[string]interface{}{"id": advId}); err != nil {
		return nil, err
	} else {
		return &adv, nil
	}
}

func (s *SystemAdvService) AdvUpdatePath(advId uint, path string) error {
	var advDao dao.Common[dao.SystemAdv]
	advDao.Query = map[string]interface{}{"id": advId}
	if err := advDao.Update(map[string]interface{}{"adv_path": path}).Error; err != nil {
		return err
	}
	return nil
}

func (s *SystemAdvService) AdvUpdateOffline(advId uint, offlineTime time.Time) error {
	var advDao dao.Common[dao.SystemAdv]
	advDao.Query = map[string]interface{}{"id": advId}
	if err := advDao.Update(map[string]interface{}{"status": dao.AdvOfflineStatus, "offline_time": offlineTime}).Error; err != nil {
		return err
	}
	return nil
}

func (s *SystemAdvService) AdvOnline(advId uint) error {
	var advDao dao.Common[dao.SystemAdv]
	advDao.Query = map[string]interface{}{"id": advId}
	if err := advDao.Update(map[string]interface{}{"status": dao.AdvOnlineStatus, "online_time": time.Now()}).Error; err != nil {
		return err
	}
	return nil
}

func (s *SystemAdvService) AdvOffline(advId uint) error {
	var advDao dao.Common[dao.SystemAdv]
	advDao.Query = map[string]interface{}{"id": advId}
	if err := advDao.Update(map[string]interface{}{"status": dao.AdvOfflineStatus, "offline_time": time.Now()}).Error; err != nil {
		return err
	}
	return nil
}

func (s *SystemAdvService) AdvUpdateSort(advId uint, sort uint) error {
	var advDao dao.Common[dao.SystemAdv]
	advDao.Query = map[string]interface{}{"id": advId}
	if err := advDao.Update(map[string]interface{}{"sort": sort}).Error; err != nil {
		return err
	}
	return nil
}

func (s *SystemAdvService) AdvDel(advId uint) error {
	var advDao dao.Common[dao.SystemAdv]
	if err := advDao.DeleteById(advId).Error; err != nil {
		return err
	}
	return nil
}

func (s *SystemAdvService) AdvFindByIds(query map[string]interface{}, orderBy string) ([]AdvListResponse, error) {
	var advServe dao.Common[dao.SystemAdv]
	if advList, err := advServe.FindAllOrderBy(query, orderBy); err != nil {
		return nil, err
	} else {
		var res []AdvListResponse

		// 查询点击量
		var advLogDao dao.Common[dao.SystemAdvLog]
		for _, v := range advList {
			item := AdvListResponse{SystemAdv: v}
			if totalClicks, err := advLogDao.Count(map[string]interface{}{"adv_id": v.Id}); err != nil {
				return nil, err
			} else {
				item.TotalClicks = totalClicks
			}
			sql := fmt.Sprintf("SELECT count(a.system_user_id) as total FROM (SELECT system_user_id,count(id) as total FROM tas_system_adv_log WHERE adv_id = %d GROUP BY system_user_id) a", v.Id)
			item.NotRepeatClicks, _ = advLogDao.RawCount(sql, "total")
			res = append(res, item)
		}
		return res, nil
	}
}
